# -*- coding: utf-8 -*-
import sys
import json
import traceback
from squirrel_core.commons.database.provider_type import ProviderType
from squirrel_core.commons.database.db_provider import DbProvider

__all__ = ["SsdbProvider"]


class SsdbProvider(DbProvider):
    ZERO_STR = "0"
    ZERO_INT = 0

    @property
    def provider_name(self):
        return ProviderType.SSDB

    def _close(self):
        self.connection.close()

    def _queue_push_back(self, key, value, *args, **kwargs):
        ret = self.connection.qpush_back(key, value)
        return SsdbProvider.ZERO_STR.encode() != ret

    def _queue_pop_back(self, key, *args, **kwargs):
        return self.connection.qpop_back(key)

    def _queue_push_front(self, key, value, *args, **kwargs):
        ret = self.connection.qpush_front(key, value)
        return SsdbProvider.ZERO_STR.encode() != ret

    def _queue_pop_front(self, key, *args, **kwargs):
        return self.connection.qpop_front(key)

    def _queue_push(self, key, value, *args, **kwargs):
        ret = self.connection.qpush_back(key, value)
        return SsdbProvider.ZERO_STR.encode() != ret

    def _queue_pop(self, key, *args, **kwargs):
        return self.connection.qpop_front(key)

    def _queue_size(self, key, *args, **kwargs):
        return self.connection.qsize(key)

    def _queue_clear(self, key, *args, **kwargs):
        self.connection.qclear(key)
        return True

    def _set_get(self, name, key, *args, **kwargs):
        return self.connection.zget(name, key)

    def _set_exists(self, name, key, *args, **kwargs):
        return self.connection.zexists(name, key)

    def _set_add(self, key, value, *args, **kwargs):
        ret = self.connection.zset(key, value, 0)
        return ret != SsdbProvider.ZERO_INT

    def _set_pop(self, key, *args, **kwargs):
        return self.connection.zpop_front(key, 1)

    def _set_del(self, name, key, *args, **kwargs):
        self.connection.zdel(name, key)
        return True

    def _set_keys(self, name, *args, **kwargs):
        limit = kwargs.get("limit", sys.maxsize)
        limit = limit or sys.maxsize
        return self.connection.zkeys(name, "", sys.maxsize * -1, sys.maxsize, limit)

    def _set_size(self, key, *args, **kwargs):
        return self.connection.zsize(key)

    def _set_clear(self, key, *args, **kwargs):
        self.connection.zclear(key)
        return True

    def _set_incr(self, name, key, num=1, *args, **kwargs):
        return self.connection.zincr(name, key, num)

    def _hash_clear(self, name, *args, **kwargs):
        self.connection.hclear(name)
        return True

    def _hash_add(self, name, key, value, *args, **kwargs):
        ret = self.connection.hset(name, key, value)
        return ret != SsdbProvider.ZERO_INT

    def _hash_get(self, name, key, *args, **kwargs):
        return self.connection.hget(name, key)

    def _save(self, item_dict, *args, **kwargs):
        ret = False
        try:
            try:
                original_type = kwargs.get("table_name", "").split("_")[-1]
            except Exception:
                original_type = item_dict.get("name_second", "")
            item_dict["original_type"] = original_type
            table_name = item_dict.pop("table_name", "")
            if not table_name:
                raise ValueError("Failed to get table name")
            data = json.dumps(item_dict, ensure_ascii=False)
            result = self.connection.qpush_back(table_name, data.encode())
            if result:
                ret = True
            self.log_msg(ret, item_dict)
        except Exception:
            err_msg = traceback.format_exc()
            self.log_msg(ret, item_dict, err_msg)
        return ret
